package nl.infodation.emr.pricingservice.ui;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.List;

import nl.infodation.emr.pricingservice.controller.ControllerFactory;
import nl.infodation.emr.pricingservice.controller.IController;
import nl.infodation.emr.pricingservice.data.AppliesSelection;
import nl.infodation.emr.pricingservice.ui.component.IView;
import nl.infodation.emr.pricingservice.ui.component.PagingComponent;
import nl.infodation.emr.pricingservice.ui.component.PagingModel;
import nl.infodation.emr.pricingservice.ui.page.SessionData;
import nl.infodation.emr.utility.Constants;
import nl.infodation.emr.utility.DateTimeUtil;
import nl.infodation.emr.utility.StringUtil;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.vaadin.annotations.AutoGenerated;
import com.vaadin.data.util.BeanItem;
import com.vaadin.event.ItemClickEvent;
import com.vaadin.event.ItemClickEvent.ItemClickListener;
import com.vaadin.ui.AbsoluteLayout;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.GridLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.Panel;
import com.vaadin.ui.TextField;

@SuppressWarnings({"unchecked", "rawtypes", "deprecation"})
public class AppliesSelectionPopup extends CustomComponent implements IView, ItemClickListener, ClickListener {

	@AutoGenerated
	private AbsoluteLayout mainLayout;
	@AutoGenerated
	private Button btnClear;
	@AutoGenerated
	private Button btnSearch;
	@AutoGenerated
	private Panel panel;
	@AutoGenerated
	private GridLayout gridLayou;
	@AutoGenerated
	private TextField tfProductId;
	@AutoGenerated
	private TextField tfProductCode;
	@AutoGenerated
	private Label lblCurrentPage;
	@AutoGenerated
	private PagingComponent pagingComponent;
	@AutoGenerated
	private AppliesSelectionList appliesSelectionList;
	private String bussinesLine;

	/**
	 * The constructor should first build the main layout, set the
	 * composition root and then do any custom initialization.
	 *
	 * The constructor will not be automatically regenerated by the
	 * visual editor.
	 */
	public AppliesSelectionPopup(AppliesSelection appliesSelection) {
		this.appliesSelection = appliesSelection;
		countryCode = appliesSelection.getCountryCode();
		bussinesLine = appliesSelection.getBussinesLine();
		initLayout();
	}
	
	private static final long serialVersionUID = 1L;
	private static final Logger LOG = LoggerFactory
			.getLogger(AppliesSelectionPopup.class);
	// paging
	private PagingModel model = new PagingModel(0);
	private AppliesSelection appliesSelection;
	
	private String countryCode;
	
	
	public AppliesSelection getAppliesSelection() {
		if (appliesSelection == null) {
			appliesSelection = new AppliesSelection();
		}
		return appliesSelection;
	}
	
	@Override
	public void initLayout() {
		buildMainLayout();
		setCompositionRoot(mainLayout);
		addListener();
		setFilterValue();
		updateListFirst();
		initialModelPaging();
	}

	private AppliesSelection getSearchItem() {
		AppliesSelection searchItem = new AppliesSelection();
		searchItem.setProductCode((String) tfProductCode.getValue());
		searchItem.setProductId((String) tfProductId.getValue());
		searchItem.setCountryCode(countryCode);
		searchItem.setBussinesLine(bussinesLine);
		return searchItem;
	}
	
	private boolean isSearching() {
		AppliesSelection searchItem = getSearchItem();
		if (!StringUtil.isEmptyOrBlank(searchItem.getProductId()) ||
			    !StringUtil.isEmptyOrBlank(searchItem.getProductCode()) ||
			    !StringUtil.isEmptyOrBlank(countryCode)) {
			
			return Boolean.TRUE;
		}
		return Boolean.FALSE;
	}
	
	private void setFilterValue() {
		AppliesSelection selection = getAppliesSelection();
		tfProductCode.setValue(selection.getProductCode());
		tfProductId.setValue(selection.getProductId());
	}
	
	private void initialModelPaging() {	
		model.addPropertyChangeListener("currentPage",
				new PropertyChangeListener() {
					public void propertyChange(final PropertyChangeEvent evt) {
						if (isSearching()) {
							updateListBySearching(model.getCurrentPage());
						} else {
							updatePageNumber();
							updateListByChangePage(model.getCurrentPage());
						}
					}
				});
		pagingComponent.setModel(model);
		updatePageNumber();
	}
	
	private void updateListByChangePage(final int page) {
		AppliesSelection selection = new AppliesSelection();
		selection.setCountryCode(countryCode);
		selection.setProductCode((String)tfProductCode.getValue());
		selection.setProductId((String)tfProductId.getValue());
		selection.setBussinesLine(bussinesLine);
		updateList(selection, page);
	}
	
	private void updateListFirst() {
		model.setCurrentPage(1);
		updateListByChangePage(1);
	}
	
	private void updateList(AppliesSelection selection, final int page) {
		IController appliesSelectionController = ControllerFactory
				.getAppliesSelectionController();
		final List<BeanItem> beans = appliesSelectionController
				.getPaginationByCriteria(selection, page,
						appliesSelectionList.getPageSize());
		appliesSelectionList.setDataSource(beans);
		// update paging
		final long totalItems = appliesSelectionController
				.getTotalNumberItemByCriteria(selection);
		final int totalPages = (int) Math.ceil(totalItems
				/ (float) appliesSelectionList.getPageSize());
		model.setTotalNumberOfPages(totalPages);
		updatePageNumber();
	}
	
	private void updateListBySearching(final int page) {
		AppliesSelection searchItem = getSearchItem();
		updateList(searchItem, page);
	}
	
	private void updatePageNumber() {
		lblCurrentPage.setValue(SessionData.getI18N().getMessage(
				Constants.CURRENT_PAGE_VALUE)
				+ model.getCurrentPage());
	}
	
	private void addListener() {
		appliesSelectionList.addListener((ItemClickListener) this);
		btnSearch.addListener((ClickListener) this);
		btnClear.addListener((ClickListener) this);
	}
	
	@Override
	public void reload() {
		
	}

	private void executeSearch() {
		model.setCurrentPage(1);
		updateListBySearching(1);
	}
	
	private void executeReset() {
		tfProductCode.setValue("");
		tfProductId.setValue("");
	}
	
	@Override
	public void buttonClick(ClickEvent event) {
		final Button source = event.getButton();

		if (source == btnSearch) {
			LOG.info(DateTimeUtil.getNow()
					+ "Search button is clicked on Applies selection popup. Searching..");
			executeSearch();

		} else if (source == btnClear) {
			LOG.info(DateTimeUtil.getNow()
					+ "Clear button is clicked on Applies selection popup. Clear all filter fields.");
			executeReset();

		}
	}
	
	@Override
	public void itemClick(ItemClickEvent event) {
		if (event.isDoubleClick()) {
			BeanItem bean = (BeanItem) event.getItem();
			
			AppliesSelection a = (AppliesSelection) bean.getBean();
			appliesSelection.setProductCode(a.getProductCode());
			appliesSelection.setProductId(a.getProductId());
			appliesSelection.setBrand(a.getBrand());
			appliesSelection.setCountryCode(a.getCountryCode());
			appliesSelection.setFamily(a.getFamily());
			appliesSelection.setLotId(a.getLotId());
			appliesSelection.setOfferId(a.getOfferId());
			appliesSelection.setSubFamily(a.getSubFamily());
			appliesSelection.setCategory(a.getCategory());
				
			// Close the popup
			getApplication().getMainWindow().removeWindow(this.getWindow());
		}
	}
	
	@AutoGenerated
	private AbsoluteLayout buildMainLayout() {
		// common part: create layout
		mainLayout = new AbsoluteLayout();
		mainLayout.setImmediate(Boolean.FALSE);
		mainLayout.setWidth("100%");
		mainLayout.setHeight("100%");
		mainLayout.setMargin(Boolean.FALSE);
		
		// top-level component properties
		setWidth("100.0%");
		setHeight("100.0%");
		
		// appliesSelectionList_1
		appliesSelectionList = new AppliesSelectionList();
		appliesSelectionList.setImmediate(Boolean.FALSE);
		appliesSelectionList.setWidth("740px");
		appliesSelectionList.setHeight("300px");
		mainLayout.addComponent(appliesSelectionList,
				"top:150.0px;left:0.0px;");
		
		// pagingComponent_1
		pagingComponent = new PagingComponent();
		pagingComponent.setImmediate(Boolean.FALSE);
		pagingComponent.setWidth("-1px");
		pagingComponent.setHeight("-1px");
		mainLayout.addComponent(pagingComponent, "top:490.0px;left:20.0px;");
		
		// lblCurrentPage
		lblCurrentPage = new Label();
		lblCurrentPage.setImmediate(Boolean.FALSE);
		lblCurrentPage.setWidth("-1px");
		lblCurrentPage.setHeight("-1px");
		lblCurrentPage.setValue("Current Page: ?");
		mainLayout.addComponent(lblCurrentPage, "top:490.0px;left:550.0px;");
		
		// panel_1
		panel = buildPanel();
		mainLayout.addComponent(panel, "top:0.0px;left:0.0px;");
		
		// btnSearch
		btnSearch = new Button();
		btnSearch.setCaption("Search");
		btnSearch.setImmediate(Boolean.TRUE);
		btnSearch.setWidth("336px");
		btnSearch.setHeight("-1px");
		mainLayout.addComponent(btnSearch, "top:100.0px;left:24.0px;");
		
		// btnClear
		btnClear = new Button();
		btnClear.setCaption("Clear");
		btnClear.setImmediate(Boolean.TRUE);
		btnClear.setWidth("340px");
		btnClear.setHeight("-1px");
		mainLayout.addComponent(btnClear, "top:100.0px;left:380.0px;");
		
		return mainLayout;
	}

	@AutoGenerated
	private Panel buildPanel() {
		// common part: create layout
		panel = new Panel();
		panel.setCaption(SessionData.getI18N().getMessage(Constants.FORM_FILTER));
		panel.setImmediate(Boolean.FALSE);
		panel.setWidth("740px");
		panel.setHeight("90px");
		
		// gridLayout_1
		gridLayou = buildGridLayout();
		panel.setContent(gridLayou);
		
		return panel;
	}

	@AutoGenerated
	private GridLayout buildGridLayout() {
		// common part: create layout
		gridLayou = new GridLayout();
		gridLayou.setImmediate(Boolean.FALSE);
		gridLayou.setWidth("100.0%");
		gridLayou.setHeight("100.0%");
		gridLayou.setMargin(Boolean.FALSE);
		gridLayou.setColumns(7);
		
		// tfProductCode
		tfProductCode = new TextField();
		tfProductCode.setCaption("Product Code");
		tfProductCode.setImmediate(Boolean.FALSE);
		tfProductCode.setWidth("150px");
		tfProductCode.setHeight("-1px");
		tfProductCode.setSecret(Boolean.FALSE);
		gridLayou.addComponent(tfProductCode, 0, 0);
		gridLayou.setComponentAlignment(tfProductCode, new Alignment(48));
		
		// tfProductId
		tfProductId = new TextField();
		tfProductId.setCaption("Product ID");
		tfProductId.setImmediate(Boolean.FALSE);
		tfProductId.setWidth("150px");
		tfProductId.setHeight("-1px");
		tfProductId.setSecret(Boolean.FALSE);
		gridLayou.addComponent(tfProductId, 1, 0);
		gridLayou.setComponentAlignment(tfProductId, new Alignment(48));
		
		return gridLayou;
	}
}
